Skip to content

refactor(repo): move typedoc reflection work into custom-theme, reduce extract-methods to a marker slicer#9073

Draft
alexisintech wants to merge 11 commits into
mainfrom
aa/docs-11892
Draft

refactor(repo): move typedoc reflection work into custom-theme, reduce extract-methods to a marker slicer#9073
alexisintech wants to merge 11 commits into
mainfrom
aa/docs-11892

Conversation

@alexisintech

@alexisintech alexisintech commented Jul 2, 2026

Copy link
Copy Markdown
Member

Description

Unifies the .typedoc/ pipeline so every reference-object and backend-api parent page carries all the info its extracted sub-docs need in a canonical ## H2 shape, and extract-methods.mjs becomes a pure text-slicer over those H2s — no reflection access, no marker block. Same generated docs.

Before: extract-methods.mjs was a second reflection walker layered on top of the markdown theme. It re-imported TypeDoc AST types, re-derived method/property partitioning, and re-invoked MarkdownThemeContext partials to build each per-method MDX file. Two places in the codebase had to agree on how methods vs properties are partitioned, which acronyms slug how, and which comment tags trigger inline extraction.

After: all reflection work lives in custom-theme.mjs, which now synthesizes:

## `name()`

H2 sections for every callable member that typedoc-plugin-markdown doesn't emit naturally (function-typed interface properties, extraMethodInterfaces, @extractMethods namespace callables like emailCode.sendCode). Backend-class methods get a ```typescript signature block injected after their natural description so all H2s share one shape.

## `name` 

H2 sections for @extractMethods namespaces with non-callable object-shape members (emailLink on SignInFutureResource) and each such non-callable member (emailLink.verification) — the same rows the marker-block builders used to write directly to sub-docs.

Overloaded backend-class methods: strip typedoc's per-overload ### Call Signature sub-headings and re-emit a single section for the primary signature, so the parent's shape is uniform across single- and multi-overload methods.

extract-methods.mjs slices those H2s pre-prettier, reshapes each into methods/<slug>.mdx (H2 → H3, then straight verbatim), and defers Properties extraction to a preWriteAsyncJob that reads the (now prettier-aligned) <!-- clerk:properties-start/end --> markers and writes properties.mdx.

Commits

  1. refactor(repo): move typedoc reflection work into custom-theme, reduce extract-methods to a marker slicer — the first move: reflection walks live in one place, extract-methods reads marker-wrapped output produced by the theme. Byte-identical to the pre-refactor docs.
  2. refactor(repo): text-slice parent H2 aggregator sections into methods sub-docs — the follow-through: parent pages carry the info directly (methods + property tables), extract-methods becomes a pure text-slicer, and the marker-block emission is deleted entirely. Byte-identical for every sub-doc; the only expected output delta is the parent pages themselves, which now show their ## name() / `## `name H2 sections in full.
  3. refactor(repo): consolidate custom-theme code-wrap and drop dead structural guards — audit follow-up on custom-theme.mjs: extract one wrapInlineTypeAsCode helper across the 5 partials that used to open-code the strip-backticks / single-wrap dance; delete the four structural type-check helpers plus coerceUnionTypeIfNeeded after confirming a single typedoc copy under pnpm makes instanceof reliable; simplify the OAuth-strategy collapse helpers. 3622 → 3464 lines. Byte-identical output.
  4. refactor(repo): data-drive custom-plugin catch-all type-link replacements — the ~45 pattern/replace entries in getCatchAllReplacements() collapse into a CATCH_ALL_TYPE_LINKS data table of [name, url] (plus a third field for the rare cases where the display name differs from the match, e.g. LoadedClerkClerk), with the regex derived from name. Five genuine one-offs stay inline (SessionResource[] array-suffix regex, Appearance<Theme>, (CreateOrganizationParams) in-page anchor, **Deprecated** full-stop, and the **Default** / **Example** / **Examples** prose rewrites). Adding a new type link is now one row. 692 → 572 lines. Byte-identical output.
  5. refactor(repo): replace FILES_WITHOUT_HEADINGS with @noHeading modifier tag — the long-standing TODO on .typedoc/custom-plugin.mjs's 33-filename allowlist finally lands. Types embedded via <Typedoc /> inside hand-written docs now opt into heading suppression at the source with /** @noHeading */; the theme's MarkdownPageEvent.END listener strips the first heading (any level H1-H6) via output.contents.replace(/^#{1,6} .+\n+/m, '') when the reflection carries the modifier. 31 declarations tagged (verified by empty-array-then-diff experiment — 3 filenames in the original list were dead). Also tagged PaginatedHookConfig because typedoc's comment inheritance for interface HookParams extends PaginatedHookConfig<…> clobbers the child's modifier tags with the parent's — the parent is @inline so it doesn't emit its own page. Byte-identical output.
  6. refactor(repo): remove dead accessor partial from custom-theme — the accessor partial in ClerkMarkdownThemeContext was never invoked: typedoc-plugin-markdown would dispatch to it from its default member partial for accessor-kind reflections, but the theme's custom member returns '' for accessors and short-circuits that path (accessors render as a compact "Property" table in memberWithGroups instead). −11 lines, byte-identical output.
  7. refactor(repo): inline swap() helper into signature partial — three-line array-index swap used exactly once by the signature partial to reorder @displayFunctionSignature output. Inlined as destructuring so the transformation is legible without a jump-away. −15 lines net, byte-identical output.
  8. refactor(repo): remove dead @paramExtension handler and tag registrationgrep -rln "@paramExtension" packages/*/src returned zero hits; the tag was registered in CUSTOM_BLOCK_TAGS but never used on any source declaration, making the ~25-line handler branch in the signature partial unreachable. Removed the handler, dropped the tag from CUSTOM_BLOCK_TAGS, and simplified the sibling @displayFunctionSignature path that shared the same split/join scaffolding. −32 lines net, byte-identical output.
  9. refactor(repo): import escapeChars from markdown-helpers instead of duplicatingescapeChars was defined twice with byte-identical bodies (once exported from .typedoc/markdown-helpers.mjs, once as a local in .typedoc/custom-theme.mjs). Import the shared version. −17 lines net, byte-identical output.

Refs

  • DOCS-11892

Checklist

  • pnpm test runs as expected. (.typedoc vitest: 16/16 pass)
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

…e extract-methods to a marker slicer

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 068c809

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Jul 7, 2026 11:32pm
swingset Ready Ready Preview, Comment Jul 7, 2026 11:32pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 66b02960-1a32-4d85-ba03-998e7be7eba6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9073

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9073

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9073

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9073

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9073

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9073

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9073

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9073

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9073

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9073

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9073

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9073

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9073

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9073

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9073

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9073

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9073

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9073

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9073

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9073

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9073

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9073

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9073

commit: 068c809

… sub-docs

Extend custom-theme.mjs so every reference-object and backend-api parent page
carries all method info in a canonical `## `name()`` / `## `name`` H2 shape:

- renderAggregatorMethodSection synthesizes sections for callable members typedoc
  doesn't emit naturally (function-typed interface properties, extraMethodInterfaces,
  @extractMethods namespace callables emitted with qualified names).
- insertSignatureBlocksIntoNaturalMethodSections injects a ```typescript block
  after each backend-class method's description so natural and synthesized sections
  share one shape.
- removeMethodH2Section strips typedoc's per-overload `### Call Signature`
  sub-headings and lets the aggregator re-emit a single section for the primary
  signature.
- renderAggregatorPropertyTableSection emits `## `name`` H2s for @extractMethods
  namespaces (listing non-callable members) and their non-callable object-shape
  members (expanding the object shape).

Reduce extract-methods.mjs to a pure text-slicer over those sections. Zero
reflection access downstream. findMethodH2Sections detects both `## `name()``
and `## `name`` shapes; reshape helpers demote to H3 and reflow into the
per-method / per-property-table sub-doc shape (byte-identical to what the
previous marker-block builders produced).

Delete the marker-block emission entirely: renderInlineMethodsBlock,
buildMethodMdx, extractCallableMembersFromDeclaration,
processExtractMethodsNamespace, buildPropertyTableDocMdx,
buildExtractMethodsNamespacePropertyTableMdx, and orphaned
appendSignatureOnlyReturns removed from custom-theme.mjs; parseMethodMarkers,
stripMethodsBlock, and both marker-block fallback paths removed from
extract-methods.mjs. The `<!-- clerk:properties-start/end -->` markers stay —
properties.mdx extraction still uses them post-prettier for column alignment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alexisintech alexisintech changed the title refactor(repo): move typedoc reflection work into custom-theme, reduce extract-methods to a marker slicer refactor(repo): unify typedoc pipeline around parent H2 aggregator sections Jul 2, 2026
…ctural guards

Audit-driven cleanups of `.typedoc/custom-theme.mjs` (3622 → 3464 lines). Every
edit was regenerated and `diff -rq`-verified against the pre-refactor baseline —
byte-identical output.

- Extract `wrapInlineTypeAsCode()`. Replaces the strip-backticks / strip-code-tags /
  conditional single-wrap block that was copy-pasted across `declarationType`,
  `unionType`, `functionType`, `arrayType`, and `reflectionType`. `functionType`'s
  split-map-join around the delimiter was decorative — global `String.replace`
  produces identical output on the whole string.

- Delete duplicate-typedoc structural guards. `isIntersectionTypeDoc` /
  `isReferenceTypeDoc` / `isReflectionTypeDoc` / `isUnionTypeDoc` /
  `coerceUnionTypeIfNeeded` existed to work around `instanceof` failing when
  multiple TypeDoc copies were loaded into the tree. `find node_modules -name
  typedoc` confirms a single copy under the current pnpm layout, so plain
  `instanceof` works reliably. Simplifies `someType`, `declaration`,
  `collectPropertyReflectionsFromIntersectionArm`, and
  `isArrayElementReferenceInliningToUnion`.

- Simplify OAuth-strategy collapse helpers. Drop the `typeof
  project.getReflectionsByKind === 'function'` runtime guard (stable in TypeDoc
  0.28) and the useless `findNamedTypeDeclaration` fallback in
  `findOAuthStrategyDeclaration` (both real `OAuthStrategy` declarations —
  `packages/shared` and `packages/backend` — are TypeAliases). Inline the
  `sourcePath` local. Convert `flattenUnionTypeMembersForOAuthCollapse` to
  `instanceof UnionType`. The collapse itself stays — TypeScript flattens
  `` `oauth_${OAuthProvider}` `` eagerly, so there is no `ReferenceType` for the
  theme to preserve.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ents

Bulk of the ~45 `pattern`/`replace` entries in `getCatchAllReplacements()` were
the same shape: bare identifier not already inside a link/code/anchor →
`[Name](/docs/…)`. Move those into a `CATCH_ALL_TYPE_LINKS` data table of
`[name, url]` (or `[name, url, linkText]` when the display name differs from the
match, as with `LoadedClerk` → `Clerk`), derive the regex from the name via a
small `catchAllBareSymbolRegex` helper, and keep the five genuine one-offs
inline (`SessionResource[]` array-suffix regex, `Appearance<Theme>`,
`(CreateOrganizationParams)` in-page anchor, `**Deprecated**` full-stop, and the
`**Default**` / `**Example**` / `**Examples**` prose rewrites).

Also splits the previous `(SignIn|SignUp)Errors` regex into two data-table
entries so every link rule is a simple identifier + url pair — makes adds
trivial.

`custom-plugin.mjs`: 692 → 572 lines. Byte-identical output vs baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…er tag

Types that clerk-docs embeds via `<Typedoc />` inside hand-written pages need
typedoc-plugin-markdown's `## Properties` group heading suppressed so the
embedded fragment doesn't collide with the parent page's heading hierarchy.
Previously this was a hardcoded array of 33 filenames + a post-hoc regex strip
in `custom-plugin.mjs` — long-standing TODO to move the trigger to the source
declaration.

- New `@noHeading` modifier tag registered in `typedoc.config.mjs` (both
  `modifierTags` and `notRenderedTags`; also added to the theme's hidden-tag
  set in the `comment` partial so it doesn't render as a `**No Heading**`
  badge — typedoc-plugin-markdown ignores `notRenderedTags` for modifier tags).
- `custom-theme.mjs` `MarkdownPageEvent.END` listener strips the first heading
  (any level H1-H6) via `output.contents.replace(/^#{1,6} .+\n+/m, '')` when
  `decl.comment.hasModifier('@noHeading')`.
- Added `/** @noHeading */` to the 31 source declarations that emit today's
  live entries (verified by empty-array-then-diff experiment; 3 filenames in
  the original list were dead — no typedoc-emitted file matched them). Also
  added `@noHeading` to `PaginatedHookConfig` because typedoc's comment
  inheritance for `interface HookParams extends PaginatedHookConfig<…>`
  replaces `HookParams`'s modifier tags with the parent's — tagging the
  parent gets it inherited (parent is `@inline` so it has no page of its own).
- Deleted `FILES_WITHOUT_HEADINGS` and its strip from `custom-plugin.mjs`.

`custom-plugin.mjs`: 573 → 514 lines. Byte-identical output vs baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The `accessor` partial in `ClerkMarkdownThemeContext` is never invoked.
typedoc-plugin-markdown would dispatch to `partials.accessor` from its default
`member` partial for accessor-kind reflections, but the theme's custom `member`
partial returns `''` for accessors and short-circuits that path — accessor
rendering happens in `memberWithGroups` (as a compact "Property" table)
instead. The header comment already hedged this ("Fallback single-row
rendering if used directly elsewhere"); nothing does.

Verified byte-identical output vs baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The `swap()` function was a three-line array-index swap used exactly once by
the `signature` partial to reorder the `@displayFunctionSignature` output.
Inline as destructuring so the transformation is legible without a jump-away.

Verified byte-identical output vs baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`grep -rln "@paramExtension" packages/*/src` returns zero hits — the tag is
never used on any source declaration. The custom handler in the `signature`
partial (which would insert extra content after the Parameters section) was
therefore unreachable. Removes the handler branch plus the tag registration
in `CUSTOM_BLOCK_TAGS`. The `@displayFunctionSignature` swap logic that
shared the same split/join scaffolding is simplified to a direct return path.

Verified byte-identical output vs baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…uplicating

`escapeChars` was defined twice — once in `.typedoc/markdown-helpers.mjs`
(exported) and once as a local function in `.typedoc/custom-theme.mjs`, with
byte-identical bodies. Import the shared version and delete the local copy.

Verified byte-identical output vs baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alexisintech alexisintech changed the title refactor(repo): unify typedoc pipeline around parent H2 aggregator sections refactor(repo): move typedoc reflection work into custom-theme, reduce extract-methods to a marker slicer Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant